namespace DaemonAPI.Middleware
{
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.IdentityModel.Tokens;
    using System.Text;
    using System.Threading.Tasks;
    using Daemon.Common.Exceptions;
    using System.IdentityModel.Tokens.Jwt;
    using Daemon.Common.Auth;
    using Microsoft.AspNetCore.Authorization;
    using Daemon.Common.Handlers;

    public static class UseJwtMiddleware
    {
        private static IConfiguration _configuration;

        public static AuthorizationPolicy LoginAccessPolicy =>
         ConfigureDefaults(new AuthorizationPolicyBuilder())
         .Build();

        private static AuthorizationPolicyBuilder ConfigureDefaults(AuthorizationPolicyBuilder builder)
        => builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser();

        public static IServiceCollection AddJwtBearExt(this IServiceCollection services, IConfiguration Configuration)
        {
            #region  get JWT
            services.Configure<JwtOptions>(Configuration.GetSection(JwtOptions.Name));
            var jwtOptions = Configuration.GetSection(JwtOptions.Name).Get<JwtOptions>();
            #endregion
            #region register jwt service

            services.AddAuthorization(options =>
                {
                    options.AddPolicy("IsLogin", LoginAccessPolicy);
                }).AddSingleton<IAuthorizationMiddlewareResultHandler, CustomAuthorizationMiddlewareResultHandler>();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Secret)),
                    ValidIssuer = jwtOptions.Issuer,
                    ValidAudience = jwtOptions.Audience,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    //ClockSkew = System.TimeSpan.FromMinutes(System.Convert.ToDouble(jwtOptions.AccessExpiration)),
                    ValidateLifetime = true
                };
                options.SaveToken = true;

                options.SecurityTokenValidators.Clear();
                options.SecurityTokenValidators.Add(new JwtSecurityTokenHandler());
            });

            #endregion

            return services;
        }
    }
}
